// Copyright 2012 Google Inc. All Rights Reserved.

package com.google.appengine.syncserver.shared;

import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;

/**
 * Class representing a property change in the android shared preference.
 */
public class PropertyChange {

  private static final String DELETED = "deleted";
  private static final String VALUE = "value";
  private static final String KEY = "key";

  /**
   *  You can either update (and therefore create) or delete a property.
   */
  public enum UpdateType {
    DELETE, UPDATE
  }

  // The type of update this is.
  private final UpdateType type;

  // key defining property.
  private final String key;

  // the value corresponding to the property.
  // This value will be null if UpdateType is delete.
  private final String value;

  /**
   * One can construct this class from the key value pair from
   * Preference class which stores the updates in the datastore.
   *
   * @param key
   * @param value this value is ignored if deleted is true.
   * @param deleted Whether this change represents a deleted value.
   */
  @JsonCreator
  public PropertyChange(
      @JsonProperty(KEY) String key,
      @JsonProperty(VALUE) String value,
      @JsonProperty(DELETED) boolean deleted) {
    this.key = key;

    // If the value represents a deleted value then we mark the type for delete.
    if (deleted) {
      this.type = UpdateType.DELETE;
      this.value = null;
    } else {
      this.type = UpdateType.UPDATE;
      this.value = value;
    }
  }

  /**
   * @return the key
   */
  @JsonProperty(KEY)
  public String getKey() {
    return key;
  }

  /**
   * @return the type
   */
  @JsonIgnore
  public UpdateType getType() {
    return type;
  }

  /**
   * @return whether this is deleted.
   */
  @JsonProperty(DELETED)
  public boolean getDeleted() {
    return type == UpdateType.DELETE;
  }

  /**
   * @return the value
   */
  @JsonProperty(VALUE)
  public String getValue() {
    return value;
  }

  /**
   * Get pretty string representation of this class.
   */
  @JsonIgnore
  public String getPrettyString() {
    switch (getType()) {
      case UPDATE:
        return String.format("Update Key = %s Value = %s", getKey(), getValue());
      case DELETE:
        return String.format("Delete Key = %s", getKey());
    }
    return null;
  }
}
